import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import javax.swing.border.BevelBorder;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.JTextArea;
import javax.swing.border.LineBorder;
import java.awt.Color;
import javax.swing.JTextField;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JProgressBar;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class ApplicationPowerMonitor {

	private String currentJobName = "",currentJobDesc = "",currentJobDuration = "",currentJobMemReq = "";
	private String currentJobPriority = "",currentJobHour = "",currentJobMinute = "",currentJobSecond = "",currentJobNPU = "";
	private String currentJobMemoryUnit = "";
	
	private String newServerPf = "", newServerMemLevel = "", newServerNPU = "", newServerCores = "", newServerDesc = "";
	private String newServerMemoryUnit = "", newServerCount = "";
	
	protected volatile SystemPowerState sps = null;
	protected volatile IJobFeeder jobFeeder = null;
	protected volatile IServerCluster serverCluster = null;
	protected volatile IServerClusterUsageData sC_UsageData = null;
	private int serverCount = 0;
	
	private JFrame frmPowerManagementSystem;
	private JTextField textJobName;
	private JTextField textJobDescription;
	private JTextField textJobDuration;
	private JTextField textJobMemReq;
	private JTextField textField_NoOfJobs;
	private JTextField text_serverPf;
	private JTextField text_serverMemLevel;
	private JTextField textJobNPU;
	private JComboBox serverDropMenu;
	private JTextField text_serverDesc;
	private JTextField text_serverNPU;
	private JTextField text_serverCores;
	private JTextArea applicationConsole;
	private JTextField text_totalPc;
	private JTextField text_totalServerCount;
	private JTextField text_totalRunningJob;
	private JTextField text_totalDueJob;
	private JTextField text_AvgPc;
	private JTextField text_AvgRunningJobs;
	private JTextField text_AvgJobsDue;
	private JProgressBar progressBar;
	private JComboBox comboBox_jobPriority;
	private JComboBox comboBox_jobStartMinute;
	private JComboBox comboBox_jobStartHour;
	private JComboBox comboBox_jobStartSecond;
	private JComboBox comboBox_jobMemoryUnit;
	private JComboBox comboBox_serverMemoryUnit;
	private JTextField text_noOfServers;

	/**
	 * Launch the application.
	 */
	public void startWindow() {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					frmPowerManagementSystem.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	/**
	 * Create the application.
	 */
	public ApplicationPowerMonitor(SystemPowerState sps, IJobFeeder jobFeeder,IServerCluster serverCluster, IServerClusterUsageData sC_UsageData) 
	{
		this.sps = sps;
		this.jobFeeder = jobFeeder;
		this.serverCluster = serverCluster;
		this.sC_UsageData = sC_UsageData;
		
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmPowerManagementSystem = new JFrame();
		frmPowerManagementSystem.setTitle("Power Management System");
		frmPowerManagementSystem.setBounds(100, 100, 640, 740);
		frmPowerManagementSystem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmPowerManagementSystem.getContentPane().setLayout(null);
		
		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBounds(6, 6, 628, 567);
		tabbedPane.setBorder(new BevelBorder(BevelBorder.RAISED, new Color(168, 201, 255), null, null, null));
		tabbedPane.setToolTipText("");
		
		frmPowerManagementSystem.getContentPane().add(tabbedPane);
		
		JPanel panel = new JPanel();
		panel.setBackground(new Color(119, 136, 153));
		tabbedPane.addTab("Add Jobs", null, panel, null);
		tabbedPane.setEnabledAt(0, true);
		tabbedPane.setBackgroundAt(0, UIManager.getColor("Button.select"));
		panel.setLayout(null);
		
		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new LineBorder(new Color(168, 201, 255), 2, true));
		panel_2.setBackground(UIManager.getColor("TextField.inactiveBackground"));
		panel_2.setBounds(32, 82, 532, 319);
		panel.add(panel_2);
		panel_2.setLayout(null);
		
		JLabel lblSingleJobCreation = new JLabel("Single Job Creation");
		lblSingleJobCreation.setForeground(new Color(255, 0, 0));
		lblSingleJobCreation.setHorizontalAlignment(SwingConstants.CENTER);
		lblSingleJobCreation.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblSingleJobCreation.setLabelFor(panel_2);
		lblSingleJobCreation.setBounds(183, 6, 160, 16);
		panel_2.add(lblSingleJobCreation);
		
		JLabel lblJobId = new JLabel("Job Name (Title):");
		lblJobId.setToolTipText("Name of the new job");
		lblJobId.setBounds(16, 39, 105, 16);
		panel_2.add(lblJobId);
		
		textJobName = new JTextField();
		textJobName.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textJobName.setText("Job1");
		textJobName.setBackground(Color.LIGHT_GRAY);
		textJobName.setBounds(220, 34, 306, 28);
		panel_2.add(textJobName);
		textJobName.setColumns(10);
		
		JLabel lblJobDescription = new JLabel("Job Description:");
		lblJobDescription.setToolTipText("Description of the new job");
		lblJobDescription.setBounds(16, 67, 105, 16);
		panel_2.add(lblJobDescription);
		
		textJobDescription = new JTextField();
		textJobDescription.setText("This is my first job");
		textJobDescription.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textJobDescription.setBackground(Color.LIGHT_GRAY);
		textJobDescription.setBounds(220, 62, 306, 28);
		panel_2.add(textJobDescription);
		textJobDescription.setColumns(10);
		
		JLabel lblJobDurationsecs = new JLabel("Job Duration (Seconds):");
		lblJobDurationsecs.setToolTipText("Duration of the job in seconds");
		lblJobDurationsecs.setBounds(16, 95, 166, 16);
		panel_2.add(lblJobDurationsecs);
		
		textJobDuration = new JTextField();
		textJobDuration.setText("60");
		textJobDuration.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textJobDuration.setBackground(Color.LIGHT_GRAY);
		textJobDuration.setBounds(220, 90, 306, 28);
		panel_2.add(textJobDuration);
		textJobDuration.setColumns(10);
		
		JLabel lblResourceRequirement = new JLabel("Memory Required (1,2,3 ...):");
		lblResourceRequirement.setToolTipText("Memory required to process the job");
		lblResourceRequirement.setBounds(16, 123, 178, 16);
		panel_2.add(lblResourceRequirement);
		
		textJobMemReq = new JTextField();
		textJobMemReq.setText("24");
		textJobMemReq.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textJobMemReq.setBackground(Color.LIGHT_GRAY);
		textJobMemReq.setBounds(220, 118, 172, 28);
		panel_2.add(textJobMemReq);
		textJobMemReq.setColumns(10);
		
		JButton button_SubmitJob = new JButton("Submit Job");
		button_SubmitJob.setToolTipText("Click to submit the above defined job");
		button_SubmitJob.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				Runnable submitJob = new Runnable()
				{
					public void run()
					{
						try 
						{
							currentJobName = textJobName.getText();
							currentJobDesc = textJobDescription.getText();
							currentJobDuration = textJobDuration.getText();
							currentJobMemReq = textJobMemReq.getText();
							currentJobPriority = (String) comboBox_jobPriority.getSelectedItem();
							currentJobNPU = textJobNPU.getText();
							currentJobMemoryUnit = (String) comboBox_jobMemoryUnit.getSelectedItem();
							currentJobHour = (String) comboBox_jobStartHour.getSelectedItem();
							currentJobMinute = (String) comboBox_jobStartMinute.getSelectedItem();
							currentJobSecond = (String) comboBox_jobStartSecond.getSelectedItem();
						} catch(Exception e) {
							writeToApplicationConsole("Warning: Some fields do not contain any value !! .. But still continuing.");
						}
						
						String checkResult = checkJobInput();
						
						if(checkResult.contentEquals("error"))
						{
							writeToApplicationConsole("Error, Some or all required values not entered !!");
							
							// CREATE A POP-UP MENU SAYING ERROR !!
						}
						
						else
						{
							System.out.println("Entered JobName: " + currentJobName);
							System.out.println("Entered JobDesc: " + currentJobDesc);
							System.out.println("Entered JobDuration: " + currentJobDuration);
							System.out.println("Entered JobMemory: " + currentJobMemReq + currentJobMemoryUnit);
							System.out.println("Entered JobPriority: " + currentJobPriority);
							System.out.println("Entered JobHour: " + currentJobHour);
							System.out.println("Entered JobMinute: " + currentJobMinute);
							System.out.println("Entered JobSecond: " + currentJobSecond);
							System.out.println("Entered JobNPE: " + currentJobNPU);
							
							if(checkResult.contentEquals("correct-all"))
							{
								try
								{
									int jobDuration = Integer.parseInt(currentJobDuration);
									long jobMemReq = Long.parseLong(currentJobMemReq);
									int jobHour = Integer.parseInt(currentJobHour);
									int jobMinute = Integer.parseInt(currentJobMinute);
									int jobSecond = Integer.parseInt(currentJobSecond);
									int jobNPE = Integer.parseInt(currentJobNPU);
									
									// Convert the memory requirement to KB
									
									if(currentJobMemoryUnit.contentEquals("MegaBytes"))
										jobMemReq = (jobMemReq * 1024);
									else if(currentJobMemoryUnit.contentEquals("GigaBytes"))
										jobMemReq = (jobMemReq * 1024 * 1024);
									
									jobFeeder.setSingleJob(currentJobName, currentJobDesc, jobDuration, jobMemReq, 
											currentJobPriority.charAt(0), jobHour, jobMinute, jobSecond, jobNPE);
									
									writeToApplicationConsole("Single job submitted !!");
								} catch(Exception e) {
									writeToApplicationConsole("Error, wrong input type entered !!");
								}
							}
							
							else if(checkResult.contentEquals("correct-some"))
							{
								try
								{
									int jobDuration = Integer.parseInt(currentJobDuration);
									long jobMemReq = Long.parseLong(currentJobMemReq);
									int jobNPE = Integer.parseInt(currentJobNPU);
									
									// Convert the memory requirement to KB
									
									if(currentJobMemoryUnit.contentEquals("MegaBytes"))
										jobMemReq = (jobMemReq * 1024);
									else if(currentJobMemoryUnit.contentEquals("GigaBytes"))
										jobMemReq = (jobMemReq * 1024 * 1024);
									
									jobFeeder.setSingleJob(currentJobName, currentJobDesc, jobDuration, jobMemReq, 
											currentJobPriority.charAt(0), -1, -1, -1, jobNPE);
									
									writeToApplicationConsole("Single job submitted !!");
								} catch(Exception e) {
									writeToApplicationConsole("Error, wrong type of value entered !!");
								}
							}
						}
					}
				};
				
				Thread submitJobThread = new Thread(submitJob);
				submitJobThread.start();
			}
		});
		
		button_SubmitJob.setForeground(UIManager.getColor("Button.darkShadow"));
		button_SubmitJob.setBackground(Color.LIGHT_GRAY);
		button_SubmitJob.setBounds(183, 287, 160, 29);
		panel_2.add(button_SubmitJob);
		
		JLabel lblJobPriorityLevel = new JLabel("Job Priority:");
		lblJobPriorityLevel.setToolTipText("Priority of the job");
		lblJobPriorityLevel.setBounds(16, 151, 81, 16);
		panel_2.add(lblJobPriorityLevel);
		
		JLabel lblJobStartHour = new JLabel("Job Starting Hour (0-23):");
		lblJobStartHour.setToolTipText("[OPTIONAL] - Starting hour of the job");
		lblJobStartHour.setBounds(16, 205, 166, 16);
		panel_2.add(lblJobStartHour);
		
		JLabel lblJobStartMinute = new JLabel("Job Starting Minute (0-59):");
		lblJobStartMinute.setToolTipText("[Optional] - Starting minute of the job");
		lblJobStartMinute.setBounds(16, 233, 178, 16);
		panel_2.add(lblJobStartMinute);
		
		JLabel lblJobStartSecond = new JLabel("Job Starting Second (0-59):");
		lblJobStartSecond.setToolTipText("[Optional] - Starting second of the job");
		lblJobStartSecond.setBounds(16, 261, 178, 16);
		panel_2.add(lblJobStartSecond);
		
		JLabel lblProcessingUnitsRequired = new JLabel("NPE Requirement (1,2,3 ...)");
		lblProcessingUnitsRequired.setToolTipText("No of cores required to process the job");
		lblProcessingUnitsRequired.setBounds(16, 179, 192, 16);
		panel_2.add(lblProcessingUnitsRequired);
		
		textJobNPU = new JTextField();
		textJobNPU.setText("2");
		textJobNPU.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textJobNPU.setColumns(10);
		textJobNPU.setBackground(Color.LIGHT_GRAY);
		textJobNPU.setBounds(220, 173, 306, 28);
		panel_2.add(textJobNPU);
		
		comboBox_jobPriority = new JComboBox();
		comboBox_jobPriority.setModel(new DefaultComboBoxModel(new String[] {"High", "Medium", "Low"}));
		comboBox_jobPriority.setBounds(220, 146, 306, 27);
		panel_2.add(comboBox_jobPriority);
		
		comboBox_jobStartHour = new JComboBox();
		comboBox_jobStartHour.setModel(new DefaultComboBoxModel(new String[] {"(As Soon As Possible)", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"}));
		comboBox_jobStartHour.setBounds(220, 200, 306, 27);
		panel_2.add(comboBox_jobStartHour);
		
		comboBox_jobStartMinute = new JComboBox();
		comboBox_jobStartMinute.setModel(new DefaultComboBoxModel(new String[] {"(As Soon As Possible)", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"}));
		comboBox_jobStartMinute.setBounds(220, 228, 306, 27);
		panel_2.add(comboBox_jobStartMinute);
		
		comboBox_jobStartSecond = new JComboBox();
		comboBox_jobStartSecond.setModel(new DefaultComboBoxModel(new String[] {"(As Soon As Possible)", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"}));
		comboBox_jobStartSecond.setBounds(220, 256, 306, 27);
		panel_2.add(comboBox_jobStartSecond);
		
		comboBox_jobMemoryUnit = new JComboBox();
		comboBox_jobMemoryUnit.setToolTipText("Memory unit for the new job");
		comboBox_jobMemoryUnit.setModel(new DefaultComboBoxModel(new String[] {"KiloBytes", "MegaBytes", "GigaBytes"}));
		comboBox_jobMemoryUnit.setSelectedIndex(1);
		comboBox_jobMemoryUnit.setBounds(404, 118, 122, 27);
		panel_2.add(comboBox_jobMemoryUnit);
		
		JPanel panel_3 = new JPanel();
		panel_3.setBorder(new LineBorder(UIManager.getColor("TextField.selectionBackground"), 2, true));
		panel_3.setBackground(UIManager.getColor("TextField.inactiveBackground"));
		panel_3.setBounds(32, 413, 532, 97);
		panel.add(panel_3);
		panel_3.setLayout(null);
		
		JLabel lblMultipleJobsCreation = new JLabel("Multiple Jobs Creation");
		lblMultipleJobsCreation.setForeground(new Color(255, 0, 0));
		lblMultipleJobsCreation.setHorizontalAlignment(SwingConstants.CENTER);
		lblMultipleJobsCreation.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblMultipleJobsCreation.setBounds(182, 6, 182, 16);
		lblMultipleJobsCreation.setLabelFor(panel_3);
		panel_3.add(lblMultipleJobsCreation);
		
		JLabel lblNoOfJobs = new JLabel("No of Jobs To Create:");
		lblNoOfJobs.setToolTipText("No of Multiple random jobs to be created");
		lblNoOfJobs.setBounds(114, 39, 134, 16);
		panel_3.add(lblNoOfJobs);
		
		textField_NoOfJobs = new JTextField();
		textField_NoOfJobs.setFont(new Font("Times New Roman", Font.PLAIN, 13));
		textField_NoOfJobs.setText("10");
		textField_NoOfJobs.setBackground(Color.LIGHT_GRAY);
		textField_NoOfJobs.setBounds(260, 34, 163, 28);
		panel_3.add(textField_NoOfJobs);
		textField_NoOfJobs.setColumns(10);
		
		JButton btnCreateJobs = new JButton("Create & Submit Jobs");
		btnCreateJobs.setToolTipText("Click to create and submit specified no of random jobs");
		btnCreateJobs.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				// Add code to submit multiple orders !!
				
				Runnable submitJobs = new Runnable()
				{
					public void run()
					{
						int jobsToSend = 0;
						
						try 
						{
							jobsToSend = Integer.parseInt(textField_NoOfJobs.getText());
							
							jobFeeder.setMultipleJobs(jobsToSend);
							
							writeToApplicationConsole("Multiple jobs sent !!");
						} catch(Exception e) {
							writeToApplicationConsole("Error ! Illegal or no value entered !!");
						}
					}
				};
				
				Thread submitJobsThread = new Thread(submitJobs);
				submitJobsThread.start();
			}
		});
		
		btnCreateJobs.setBounds(182, 67, 163, 29);
		panel_3.add(btnCreateJobs);
		
		JTextArea txtrThisTabIs_1 = new JTextArea();
		txtrThisTabIs_1.setBackground(new Color(119, 136, 153));
		txtrThisTabIs_1.setWrapStyleWord(true);
		txtrThisTabIs_1.setLineWrap(true);
		txtrThisTabIs_1.setRows(3);
		txtrThisTabIs_1.setEditable(false);
		txtrThisTabIs_1.setText("This tab is used for adding new jobs into the system.\n\n1. The Single Job GUI creates a single job based on the provided information.\n2. The Multiple Job GUI creates specified no of jobs, with random data.");
		txtrThisTabIs_1.setBounds(48, 6, 494, 64);
		panel.add(txtrThisTabIs_1);
		
		JPanel panel_1 = new JPanel();
		panel_1.setBackground(new Color(119, 136, 153));
		tabbedPane.addTab("System Status", null, panel_1, null);
		panel_1.setLayout(null);
		
		JTextArea txtrThisTabIs = new JTextArea();
		txtrThisTabIs.setEditable(false);
		txtrThisTabIs.setBounds(6, 6, 591, 16);
		txtrThisTabIs.setLineWrap(true);
		txtrThisTabIs.setBackground(new Color(119, 136, 153));
		txtrThisTabIs.setWrapStyleWord(true);
		txtrThisTabIs.setText("Select server and click the button to view individual server details.");
		panel_1.add(txtrThisTabIs);
		
		JLabel lblResourceStatus = new JLabel("Overall System Status");
		lblResourceStatus.setForeground(new Color(0, 255, 0));
		lblResourceStatus.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblResourceStatus.setHorizontalAlignment(SwingConstants.CENTER);
		lblResourceStatus.setBounds(231, 136, 153, 16);
		panel_1.add(lblResourceStatus);
		
		serverDropMenu = new JComboBox();
		serverDropMenu.setToolTipText("Click to view servers in the system");
		
		Runnable updateMenu = new Runnable()
		{
			public void run()
			{
				while(true)
				{
					serverCount = sps.getServerNumber();
					String[] dropDownMenuList = new String[serverCount];
					
					for(int i=0;i<serverCount;i++)
						dropDownMenuList[i] = "Server " + i;
					
					DefaultComboBoxModel oldModel = (DefaultComboBoxModel) serverDropMenu.getModel();
					DefaultComboBoxModel newModel = new DefaultComboBoxModel(dropDownMenuList);
					
					boolean modelComparision = compareModels(oldModel,newModel);
					
					if(modelComparision == false)
						serverDropMenu.setModel(newModel);
					
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
					
			}
		};
		
		Thread updateMenuThread = new Thread(updateMenu);
		updateMenuThread.start();
		
		serverDropMenu.setBounds(203, 29, 171, 27);
		panel_1.add(serverDropMenu);
		serverDropMenu.setMaximumRowCount(10);
		serverDropMenu.setFont(new Font("Lucida Grande", Font.PLAIN, 13));
		//serverDropMenu.setModel(new DefaultComboBoxModel(new String[] {"Server 0"}));
		//serverDropMenu.setSelectedIndex(0);
		
				
		
		JLabel lblSelectResource = new JLabel("Select Server :");
		lblSelectResource.setBounds(97, 34, 93, 16);
		panel_1.add(lblSelectResource);
		
		JButton btnOpenServerWindow = new JButton("Open Server Window");
		btnOpenServerWindow.setToolTipText("Click to view selected server's details");
		btnOpenServerWindow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		btnOpenServerWindow.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				// Code for launching a new server window based on the selected item form drop down menu
				
				String selectedServer = (String) serverDropMenu.getSelectedItem();
				
				if(selectedServer != null)
				{
					writeToApplicationConsole("Selected [" + selectedServer + "] ... Opening Server Window !!");
					
					String selectedKey = selectedServer.substring(7, selectedServer.length());
					
					System.out.println("Key Selected: " + selectedKey);
					
					ServerWindow newWindow = new ServerWindow(serverCluster.getServer(Integer.parseInt(selectedKey)),sps,sC_UsageData);
					newWindow.startWindow();
				}
				
				else
					writeToApplicationConsole("No Server Selected !!");
			}
		});
		
		btnOpenServerWindow.setBounds(386, 29, 153, 29);
		panel_1.add(btnOpenServerWindow);
		
		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(72, 122, 467, 12);
		panel_1.add(separator_1);
		
		JLabel lblSystemPowerConsumption = new JLabel("Total Power Consumption (Watt-Hour):");
		lblSystemPowerConsumption.setBounds(97, 180, 250, 16);
		panel_1.add(lblSystemPowerConsumption);
		
		text_totalPc = new JTextField();
		text_totalPc.setHorizontalAlignment(SwingConstants.CENTER);
		text_totalPc.setText("0");
		text_totalPc.setForeground(new Color(255, 255, 255));
		text_totalPc.setBackground(new Color(123, 104, 238));
		text_totalPc.setEditable(false);
		text_totalPc.setBounds(366, 174, 153, 28);
		panel_1.add(text_totalPc);
		text_totalPc.setColumns(10);
		
		JLabel lblNoOfServers = new JLabel("Total Server Count:");
		lblNoOfServers.setBounds(97, 208, 129, 16);
		panel_1.add(lblNoOfServers);
		
		text_totalServerCount = new JTextField();
		text_totalServerCount.setText("0");
		text_totalServerCount.setHorizontalAlignment(SwingConstants.CENTER);
		text_totalServerCount.setForeground(Color.WHITE);
		text_totalServerCount.setEditable(false);
		text_totalServerCount.setColumns(10);
		text_totalServerCount.setBackground(new Color(123, 104, 238));
		text_totalServerCount.setBounds(366, 202, 153, 28);
		panel_1.add(text_totalServerCount);
		
		JLabel lblTotalRunningJob = new JLabel("Total No of Jobs Running:");
		lblTotalRunningJob.setBounds(97, 236, 171, 16);
		panel_1.add(lblTotalRunningJob);
		
		text_totalRunningJob = new JTextField();
		text_totalRunningJob.setText("0");
		text_totalRunningJob.setHorizontalAlignment(SwingConstants.CENTER);
		text_totalRunningJob.setForeground(Color.WHITE);
		text_totalRunningJob.setEditable(false);
		text_totalRunningJob.setColumns(10);
		text_totalRunningJob.setBackground(new Color(123, 104, 238));
		text_totalRunningJob.setBounds(366, 230, 153, 28);
		panel_1.add(text_totalRunningJob);
		
		JLabel lblTotalJobsDue = new JLabel("Total No Of Unprocessed Jobs:");
		lblTotalJobsDue.setBounds(97, 264, 197, 16);
		panel_1.add(lblTotalJobsDue);
		
		text_totalDueJob = new JTextField();
		text_totalDueJob.setText("0");
		text_totalDueJob.setHorizontalAlignment(SwingConstants.CENTER);
		text_totalDueJob.setForeground(Color.WHITE);
		text_totalDueJob.setEditable(false);
		text_totalDueJob.setColumns(10);
		text_totalDueJob.setBackground(new Color(123, 104, 238));
		text_totalDueJob.setBounds(366, 258, 153, 28);
		panel_1.add(text_totalDueJob);
		
		JSeparator separator_2 = new JSeparator();
		separator_2.setBounds(162, 299, 283, 12);
		panel_1.add(separator_2);
		
		JLabel lblSystemFacts = new JLabel("System Facts");
		lblSystemFacts.setForeground(new Color(0, 255, 0));
		lblSystemFacts.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblSystemFacts.setHorizontalAlignment(SwingConstants.CENTER);
		lblSystemFacts.setBounds(260, 323, 93, 16);
		panel_1.add(lblSystemFacts);
		
		JLabel lblAverageServerPower = new JLabel("Average Power Consumption/Server:");
		lblAverageServerPower.setBounds(97, 355, 232, 16);
		panel_1.add(lblAverageServerPower);
		
		text_AvgPc = new JTextField();
		text_AvgPc.setText("0");
		text_AvgPc.setHorizontalAlignment(SwingConstants.CENTER);
		text_AvgPc.setForeground(Color.WHITE);
		text_AvgPc.setEditable(false);
		text_AvgPc.setColumns(10);
		text_AvgPc.setBackground(new Color(123, 104, 238));
		text_AvgPc.setBounds(366, 349, 153, 28);
		panel_1.add(text_AvgPc);
		
		JLabel lblAverageRunningJobsserver = new JLabel("Average Running Jobs/Server:");
		lblAverageRunningJobsserver.setBounds(97, 383, 197, 16);
		panel_1.add(lblAverageRunningJobsserver);
		
		text_AvgRunningJobs = new JTextField();
		text_AvgRunningJobs.setText("0");
		text_AvgRunningJobs.setHorizontalAlignment(SwingConstants.CENTER);
		text_AvgRunningJobs.setForeground(Color.WHITE);
		text_AvgRunningJobs.setEditable(false);
		text_AvgRunningJobs.setColumns(10);
		text_AvgRunningJobs.setBackground(new Color(123, 104, 238));
		text_AvgRunningJobs.setBounds(366, 377, 153, 28);
		panel_1.add(text_AvgRunningJobs);
		
		JLabel lblAverageJobsDueserver = new JLabel("Average Unprocessed Jobs/Server:");
		lblAverageJobsDueserver.setBounds(97, 411, 232, 16);
		panel_1.add(lblAverageJobsDueserver);
		
		text_AvgJobsDue = new JTextField();
		text_AvgJobsDue.setText("0");
		text_AvgJobsDue.setHorizontalAlignment(SwingConstants.CENTER);
		text_AvgJobsDue.setForeground(Color.WHITE);
		text_AvgJobsDue.setEditable(false);
		text_AvgJobsDue.setColumns(10);
		text_AvgJobsDue.setBackground(new Color(123, 104, 238));
		text_AvgJobsDue.setBounds(366, 405, 153, 28);
		panel_1.add(text_AvgJobsDue);
		
		progressBar = new JProgressBar();
		progressBar.setToolTipText("Power consumption as a percentage of maximum consumable power of the system");
		progressBar.setStringPainted(true);
		progressBar.setBounds(72, 491, 477, 20);
		
		Runnable progressBarUpdate = new Runnable()
		{
			public void run()
			{
				while(true)
				{
					// Update the value of the progress bar
					
					progressBar.setMaximum(calculateMaxPowerConsumption());
					
					try
					{
						progressBar.setValue((int) Double.parseDouble(text_totalPc.getText()));
					} catch (Exception e) {
						System.out.println("Total Power Consumption Value null or not present !!");
					}
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		
		Thread progressBarUpdateThread = new Thread(progressBarUpdate);
		progressBarUpdateThread.start();
		
		panel_1.add(progressBar);
		
		JLabel lblTotalSystemPower = new JLabel("Total Power Consumption Indicator");
		lblTotalSystemPower.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblTotalSystemPower.setForeground(new Color(0, 255, 0));
		lblTotalSystemPower.setBounds(203, 463, 242, 16);
		panel_1.add(lblTotalSystemPower);
		
		JButton btnOpenSystemStatus = new JButton("View System Status");
		btnOpenSystemStatus.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				// Code to create the system usage window
				
				if(serverCluster != null)
				{
					if(serverCluster.getServerCount() > 0)
					{
						SystemUsageWindow systemWindow = new SystemUsageWindow(serverCluster);
						systemWindow.startWindow();
					}
				}
			}
		});
		
		btnOpenSystemStatus.setToolTipText("Click to open view overall system status window");
		btnOpenSystemStatus.setForeground(Color.BLUE);
		btnOpenSystemStatus.setBackground(Color.LIGHT_GRAY);
		btnOpenSystemStatus.setBounds(202, 95, 188, 29);
		panel_1.add(btnOpenSystemStatus);
		
		JLabel lblClickTheButton = new JLabel("Click the button below for a graphical view of the overall system performance.");
		lblClickTheButton.setBounds(6, 67, 513, 16);
		panel_1.add(lblClickTheButton);
		tabbedPane.setEnabledAt(1, true);
		tabbedPane.setSelectedIndex(0);
		
		startSystemStatusThread();
		
		JPanel panel_5 = new JPanel();
		panel_5.setBackground(new Color(119, 136, 153));
		tabbedPane.addTab("Add Server", null, panel_5, null);
		panel_5.setLayout(null);
		
		JTextArea txtrThisTabIs_2 = new JTextArea();
		txtrThisTabIs_2.setBackground(new Color(119, 136, 153));
		txtrThisTabIs_2.setText("This tab is used to add servers to the system.\n\nServers can be added by entering the specified information below, in the correct format.");
		txtrThisTabIs_2.setEditable(false);
		txtrThisTabIs_2.setBounds(6, 19, 570, 54);
		panel_5.add(txtrThisTabIs_2);
		
		JPanel panel_6 = new JPanel();
		panel_6.setBackground(Color.WHITE);
		panel_6.setBounds(6, 102, 570, 409);
		panel_5.add(panel_6);
		panel_6.setLayout(null);
		
		JLabel lblEnterTheFollowing = new JLabel("Enter the following information");
		lblEnterTheFollowing.setBounds(16, 44, 203, 16);
		lblEnterTheFollowing.setHorizontalAlignment(SwingConstants.CENTER);
		panel_6.add(lblEnterTheFollowing);
		
		JLabel lblResourcePowerFactor = new JLabel("Server Performance Value (Decimal):");
		lblResourcePowerFactor.setToolTipText("Server Efficiency Value");
		lblResourcePowerFactor.setBounds(26, 78, 225, 16);
		panel_6.add(lblResourcePowerFactor);
		
		text_serverPf = new JTextField();
		text_serverPf.setBounds(295, 72, 269, 28);
		text_serverPf.setText("2.66");
		text_serverPf.setBackground(Color.LIGHT_GRAY);
		panel_6.add(text_serverPf);
		text_serverPf.setColumns(10);
		
		JLabel lblResourceProportion = new JLabel("Server Memory (1,2,3 ...):");
		lblResourceProportion.setToolTipText("Amount of memory to be assigned to the server");
		lblResourceProportion.setBounds(25, 106, 163, 16);
		panel_6.add(lblResourceProportion);
		
		text_serverMemLevel = new JTextField();
		text_serverMemLevel.setBounds(295, 100, 137, 28);
		text_serverMemLevel.setText("24");
		text_serverMemLevel.setBackground(Color.LIGHT_GRAY);
		panel_6.add(text_serverMemLevel);
		text_serverMemLevel.setColumns(10);
		
		JLabel lblSingleResourceCreation = new JLabel("SERVER/NODE CREATION");
		lblSingleResourceCreation.setForeground(new Color(255, 0, 0));
		lblSingleResourceCreation.setBounds(181, 6, 203, 16);
		lblSingleResourceCreation.setFont(new Font("Lucida Grande", Font.BOLD, 13));
		lblSingleResourceCreation.setHorizontalAlignment(SwingConstants.CENTER);
		panel_6.add(lblSingleResourceCreation);
		
		JButton btnCreateResource = new JButton("Create Server(s)");
		btnCreateResource.setToolTipText("Click to create above defined server");
		btnCreateResource.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				// Code to add a new Server to the system
				
				try
				{
					newServerPf = text_serverPf.getText();
					newServerMemLevel = text_serverMemLevel.getText();
					newServerNPU = text_serverNPU.getText();
					newServerCores = text_serverCores.getText();
					newServerMemoryUnit = (String) comboBox_serverMemoryUnit.getSelectedItem();
					newServerDesc = text_serverDesc.getText();
					newServerCount = text_noOfServers.getText();
					
					// Input the memory unit for server memory and do as required
				} catch(Exception e) {
					writeToApplicationConsole("Warning: Some fields maybe empty !! .. But still continuing");
				}
				
				String checkResult = checkNewServerInput();
				
				if(checkResult.contentEquals("error"))
					writeToApplicationConsole("Error !! Some required values are missing !");
				
				else
				{
					try
					{
						double serverPf = Double.parseDouble(newServerPf);
						long serverMemLevel = Long.parseLong(newServerMemLevel);
						int serverNPU = Integer.parseInt(newServerNPU);
						int serverCores = Integer.parseInt(newServerCores);
						int serverCount = Integer.parseInt(newServerCount);
						
						if(newServerMemoryUnit.contentEquals("MegaBytes"))
							serverMemLevel = (serverMemLevel * 1024);
						else if(newServerMemoryUnit.contentEquals("GigaBytes"))
							serverMemLevel = (serverMemLevel * 1024 * 1024);
						
						for(int i=0;i<serverCount;i++)
						{
							if(checkResult.contentEquals("correct-all"))
								serverCluster.addServer(serverPf, serverMemLevel, serverNPU, serverCores, newServerDesc);
							
							else if(checkResult.contentEquals("correct-some"))
								serverCluster.addServer(serverPf, serverMemLevel, serverNPU, serverCores, "N/A");
							
							writeToApplicationConsole("New Server Created !!");
						}
						
						/*if(checkResult.contentEquals("correct-all"))
							serverCluster.addServer(serverPf, serverMemLevel, serverNPU, serverCores, newServerDesc);
						
						else if(checkResult.contentEquals("correct-some"))
							serverCluster.addServer(serverPf, serverMemLevel, serverNPU, serverCores, "N/A");
						
						writeToApplicationConsole("New Server Created !!");*/
					} catch(Exception e) {
						writeToApplicationConsole("Error, Illegal values entered !!");
					}
				}
			}
		});
		
		btnCreateResource.setBounds(218, 251, 130, 29);
		panel_6.add(btnCreateResource);
		
		JSeparator separator = new JSeparator();
		separator.setBounds(16, 306, 536, 12);
		separator.setForeground(Color.DARK_GRAY);
		panel_6.add(separator);
		
		JTextArea txtrPleaseNoteThat = new JTextArea();
		txtrPleaseNoteThat.setEditable(false);
		txtrPleaseNoteThat.setLineWrap(true);
		txtrPleaseNoteThat.setText("Please note that there is no option to specify the server KEY.\n\nThe servers are assigned consecutive numeric KEY value (starting from 0), automatically at the time of creation.");
		txtrPleaseNoteThat.setBackground(new Color(100, 149, 237));
		txtrPleaseNoteThat.setBounds(37, 330, 498, 69);
		panel_6.add(txtrPleaseNoteThat);
		
		JLabel lblServerDescription = new JLabel("Server Description :");
		lblServerDescription.setToolTipText("Decription for the new server");
		lblServerDescription.setBounds(26, 134, 130, 16);
		panel_6.add(lblServerDescription);
		
		text_serverDesc = new JTextField();
		text_serverDesc.setText("Server for Image Processing");
		text_serverDesc.setColumns(10);
		text_serverDesc.setBackground(Color.LIGHT_GRAY);
		text_serverDesc.setBounds(295, 128, 269, 28);
		panel_6.add(text_serverDesc);
		
		JLabel lblServerNpu = new JLabel("Number of Processors (1,2,3 ...):");
		lblServerNpu.setToolTipText("No of processors in the new server");
		lblServerNpu.setBounds(26, 162, 203, 16);
		panel_6.add(lblServerNpu);
		
		text_serverNPU = new JTextField();
		text_serverNPU.setText("2");
		text_serverNPU.setColumns(10);
		text_serverNPU.setBackground(Color.LIGHT_GRAY);
		text_serverNPU.setBounds(295, 156, 269, 28);
		panel_6.add(text_serverNPU);
		
		JLabel lblNumberOfCores = new JLabel("Number of Cores (1,2,3 ...):");
		lblNumberOfCores.setToolTipText("No of cores within each processor of the new server");
		lblNumberOfCores.setBounds(26, 190, 176, 16);
		panel_6.add(lblNumberOfCores);
		
		text_serverCores = new JTextField();
		text_serverCores.setText("6");
		text_serverCores.setColumns(10);
		text_serverCores.setBackground(Color.LIGHT_GRAY);
		text_serverCores.setBounds(295, 184, 269, 28);
		panel_6.add(text_serverCores);
		
		comboBox_serverMemoryUnit = new JComboBox();
		comboBox_serverMemoryUnit.setToolTipText("Memory unit for the new server");
		comboBox_serverMemoryUnit.setModel(new DefaultComboBoxModel(new String[] {"KiloBytes", "MegaBytes", "GigaBytes"}));
		comboBox_serverMemoryUnit.setSelectedIndex(2);
		comboBox_serverMemoryUnit.setBounds(444, 101, 120, 27);
		panel_6.add(comboBox_serverMemoryUnit);
		
		JLabel lblNoOfServersnodes = new JLabel("No of Servers/Nodes to create (1,2,3 ...):");
		lblNoOfServersnodes.setToolTipText("No of duplicate servers to create");
		lblNoOfServersnodes.setBounds(26, 218, 254, 16);
		panel_6.add(lblNoOfServersnodes);
		
		text_noOfServers = new JTextField();
		text_noOfServers.setText("1");
		text_noOfServers.setColumns(10);
		text_noOfServers.setBackground(Color.LIGHT_GRAY);
		text_noOfServers.setBounds(295, 212, 269, 28);
		panel_6.add(text_noOfServers);
		
		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(6, 602, 628, 89);
		frmPowerManagementSystem.getContentPane().add(scrollPane_1);
		
		applicationConsole = new JTextArea();
		applicationConsole.setForeground(Color.WHITE);
		applicationConsole.setEditable(false);
		applicationConsole.setBackground(Color.BLACK);
		scrollPane_1.setViewportView(applicationConsole);
		
		JLabel lblApplicationConsole = new JLabel("Application Console");
		lblApplicationConsole.setBounds(251, 585, 127, 16);
		frmPowerManagementSystem.getContentPane().add(lblApplicationConsole);
	}
	
	public JComboBox getServerDropMenu() {
		return serverDropMenu;
	}
	
	private String checkJobInput()
	{
		if(!currentJobName.isEmpty() && !currentJobDesc.isEmpty() && !currentJobDuration.isEmpty() && !currentJobMemReq.isEmpty() 
				&& !currentJobPriority.isEmpty() && !currentJobNPU.isEmpty())
		{
			if((currentJobHour.contentEquals("(As Soon As Possible)"))
					&& (currentJobMinute.contentEquals("(As Soon As Possible)"))
					&& (currentJobSecond.contentEquals("(As Soon As Possible)")))
				return "correct-some";
			else if((!currentJobHour.contentEquals("(As Soon As Possible)"))
					&& (!currentJobMinute.contentEquals("(As Soon As Possible)"))
					&& (!currentJobSecond.contentEquals("(As Soon As Possible)")))
				return "correct-all";
			else
				return "error";
			
			/*if(currentJobHour.isEmpty() && currentJobMinute.isEmpty() && currentJobSecond.isEmpty())
				return "correct-some";
			else if(!currentJobHour.isEmpty() && !currentJobMinute.isEmpty() && !currentJobSecond.isEmpty())
				return "correct-all";
			else 
				return "error";*/
		}
		
		return "error";
	}
	
	private String checkNewServerInput()
	{
		if(!newServerPf.isEmpty() && !newServerMemLevel.isEmpty() && !newServerNPU.isEmpty() && !newServerCores.isEmpty()
				&& !newServerCount.isEmpty())
		{
			if(newServerDesc.isEmpty())
				return "correct-some";
			else
				return "correct-all";
		}
		
		return "error";
	}
	
	public JTextArea getApplicationConsole() {
		return applicationConsole;
	}
	
	public void writeToApplicationConsole(String msg)
	{
		getApplicationConsole().append(msg + "\n");
		getApplicationConsole().setCaretPosition(getApplicationConsole().getDocument().getLength());
	}
	public JTextField getText_totalPc() {
		return text_totalPc;
	}
	public JTextField getText_totalServerCount() {
		return text_totalServerCount;
	}
	public JTextField getText_totalRunningJob() {
		return text_totalRunningJob;
	}
	public JTextField getText_totalDueJob() {
		return text_totalDueJob;
	}
	public JTextField getText_AvgPc() {
		return text_AvgPc;
	}
	public JTextField text_AvgRunningJobs() {
		return text_AvgRunningJobs;
	}
	public JTextField getText_AvgJobsDue() {
		return text_AvgJobsDue;
	}
	
	private void startSystemStatusThread()
	{
		Runnable updateSystemStatus = new Runnable()
		{
			public void run()
			{
				while(true)
				{
					// Code for updating the System Status
					
					double totalPc = 0.0;
					int totalServerCount = serverCluster.getServerCount();
					int totalRunningJobs = 0;
					int totalDueJobs = 0;
					
					if(totalServerCount > 0)
					{
						for(int i=0;i<totalServerCount;i++)
						{
							totalPc = totalPc + serverCluster.getServer(i).getPowerConsumption();
							totalRunningJobs = totalRunningJobs + serverCluster.getServer(i).getRunningJobCount();
							totalDueJobs = totalDueJobs + serverCluster.getServer(i).getDueJobCount();
						}
						
						text_totalDueJob.setText(null);
						text_totalDueJob.setText(String.valueOf(totalDueJobs));
						
						text_totalPc.setText(null);
						text_totalPc.setText(String.valueOf(totalPc));
						
						text_totalRunningJob.setText(null);
						text_totalRunningJob.setText(String.valueOf(totalRunningJobs));
						
						text_totalServerCount.setText(null);
						text_totalServerCount.setText(String.valueOf(totalServerCount));
						
						text_AvgJobsDue.setText(null);
						text_AvgJobsDue.setText(String.valueOf((int)(totalDueJobs/totalServerCount)));
						
						text_AvgPc.setText(null);
						text_AvgPc.setText(String.valueOf((int) (totalPc/totalServerCount)));
						
						text_AvgRunningJobs.setText(null);
						text_AvgRunningJobs.setText(String.valueOf((int) (totalRunningJobs/totalServerCount)));
					}	
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		
		Thread updateSystemStatusThread = new Thread(updateSystemStatus);
		updateSystemStatusThread.start();
	}
	
	public JProgressBar getProgressBar() {
		return progressBar;
	}
	
	private int calculateMaxPowerConsumption()
	{
		double maxConsumption = 0.0;
		
		for(int i=0;i<serverCluster.getServerCount();i++)
			maxConsumption = maxConsumption + serverCluster.getServer(i).getMaxPower();
		
		return (int) maxConsumption;
	}
	public JComboBox getComboBox_jobPriority() {
		return comboBox_jobPriority;
	}
	public JComboBox getComboBox_jobStartMinute() {
		return comboBox_jobStartMinute;
	}
	public JComboBox getComboBox_jobStartHour() {
		return comboBox_jobStartHour;
	}
	public JComboBox getComboBox_jobStartSecond() {
		return comboBox_jobStartSecond;
	}
	public JComboBox getComboBox_jobMemoryUnit() {
		return comboBox_jobMemoryUnit;
	}
	public JComboBox getComboBox_serverMemoryUnit() {
		return comboBox_serverMemoryUnit;
	}
	
	private boolean compareModels(DefaultComboBoxModel oldModel,DefaultComboBoxModel newModel)
	{		
		if(oldModel.getSize() == newModel.getSize())
		{
			// Check for individual elements
			
			for(int i=0;i<oldModel.getSize();i++)
			{
				if(!oldModel.getElementAt(i).equals(newModel.getElementAt(i)))
					return false;
			}
		}
		
		else
			return false;
		
		return true;
	}
	public JTextField getText_noOfServers() {
		return text_noOfServers;
	}
}
